<%@ page import="java.util.*" %>
<%@ page import="bw.note.NotebookManager" %>
<%@ page import="bw.util.DateFactory" %>
<%
  String defaultNotebookPage = ( new NotebookManager() ).getDefaultPage(); 

  String notebookPageName = ( NotebookManager.DEFAULT_PAGE_NAME.equals( defaultNotebookPage ) ? "Page One" : defaultNotebookPage ); 
%>
<html>
<head>
<title>notebook!</title>
<link rel=STYLESHEET type="text/css" href="style.css">
<link rel="SHORTCUT ICON" href="images/favicon.ico">

<!-- Dependencies --> 
<script type="text/javascript" src="include/yui_2.6/yahoo-dom-event.js"></script>

<!-- Utility Dependencies --> 
<script type="text/javascript" src="include/yui_2.6/element-beta-min.js"></script>  
<!-- Connect -->
<script type="text/javascript" src="include/yui_2.6/connection-min.js"></script>
<!-- Animate -->
<script type="text/javascript" src="include/yui_2.6/animation-min.js"></script> 

<!-- My Tiny Editor -->
<script type="text/javascript" src="include/tinyEditor.js"></script>

<!-- Sidebar -->
<script type="text/javascript" src="include/sidebar.js"></script>

<style>

.noteHeader { padding:5px 10px 5px 10px; 
                         background:#294766; 
                         font-weight:bold;
                         color: #FFFFFF; }

.noteBody { padding:5px 10px 5px 10px; text-align:left; color:#FFFFFF;
                 line-height:1.3; 
	         overflow:hidden; 
                 font-weight:bold; background:#143D66; }

.editor { border:none; }

.saveNoteLink { visibility:hidden; }

.notebookPageContainer { overflow:hidden; position:absolute; top:60px; left:20px; height:50px; width:50px; }

.notebookPage { position:absolute; top:0px; width:350px; height:100%; }

#scrubberBar { position:absolute; overflow:hidden; width:350px; height:2px; bottom:65px; background:#294766; }
#scrubber { position:absolute; top:0px; left:0px; height:2px; width:50px; background:#336699; }

</style>

</head>
<body style="overflow:hidden; background:#000033; margin:0px; padding:0px;"> 

<div id="notebookHolder" style="background:#003366; position:relative; width:100%; height:100%; z-index:2;">

<!-- <div id="pageNameHolder" class="notebookPageName">
<%= notebookPageName %>
</div>
-->

<div class="supplementaryNav">
<a class="supnavlink" href="javascript:addNotebookEntry()">add page</a> |
<a class="supnavlink" href="javascript:sidebar.showSidebar( true )">show index</a>
</div>

<div id="container" class="notebookPageContainer">
<div id="pages" style="position:absolute; top:0px; left:0px;"></div>
</div>

<div id="scrubberBar">
<div id="scrubber"></div>
</div>

<jsp:include page="nav.html" />

</div>

<div id="notebookIndex" style="width:230px; position:absolute; top:0px; right:0px; z-index:1; padding:10px; color:#ffffff;">

<div style="padding-bottom:15px;">
<table width="100%" cellpadding="0" cellspacing="0" margin="0">
<tr><td><b>notebook index</b></td><td align="right"><a class="supnavlink" href="javascript:sidebar.showSidebar( false )">hide index</a></td></tr>
</table>
</div>

<div class="notebookIndexEntry">
<table width="100%" cellpadding="0" cellspacing="0" margin="0">
<tr><td><span id="indexIndicator_def" class="indexIndicator"><%= ( NotebookManager.DEFAULT_PAGE_NAME.equals( defaultNotebookPage ) ? "&#9658; " : "" ) %></span><a href="javascript:gotoPage( '<%= NotebookManager.DEFAULT_PAGE_NAME %>', 'def' )" class="notebookIndexLink">Page One</a></td><td align="right"></td></tr>
</table>
</div>

<div id="notebookPages"></div>

<div class="notebookIndexEntry">
<table width="100%" cellpadding="0" cellspacing="0" margin="0">
<tr><td colspan="2" align="right">
<div id="addNewPage"><a class="supnavlink" href="javascript:showNewPageField()">add new page</a></div>
</td></tr>
</table>
</div>

</div>

</body>

<script>

var sidebar = new Sidebar( 'notebookHolder' );

//default page
var notebookPageName = '<%= defaultNotebookPage %>';

var addNewPageLink;

function showNewPageField ()
{
  var t = document.createElement( "input" );
  t.setAttribute( "type", "text" );
  t.setAttribute( "name", "pageName" );
  t.setAttribute( "maxlength", "25" );
  t.setAttribute( "style", "font-size:x-small; width:100%;" );
  t.setAttribute( "onKeyPress", "addNewPage(event,this)" );

  var c = document.getElementById( "addNewPage" );
  addNewPageLink = c.firstChild;
  c.replaceChild( t, c.firstChild );

  var b = document.createElement( "div" );
  b.setAttribute( "class", "cancelNewsSource" );

  var cancelLink = document.createElement( "a" );
  cancelLink.setAttribute( "href", "javascript:cancelAddNewPage()" );
  cancelLink.setAttribute( "class", "supnavlink" );
  cancelLink.appendChild( document.createTextNode( "Cancel" ) );

  b.appendChild( cancelLink );

  c.appendChild( b );

  t.focus();
}

function addNewPage ( evt, n )
{
  if ( evt.which == 13 ) {
    //alert( "adding index entry: " + n.value );

    var surl = 'notebook?action=addPage&name=' + escape( n.value );

    var callback = 
    {
      success : handleAddPage,
      failure : handleFailure
    };

    YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
  }
}

function handleAddPage ( obj )
{
  cancelAddNewPage();
  buildIndex( obj );
}

function cancelAddNewPage ()
{
  var c = document.getElementById( "addNewPage" );
  while ( c.hasChildNodes() ) { c.removeChild( c.firstChild ); }
  c.appendChild( addNewPageLink );
}

function deletePage ( page )
{
  var surl = 'notebook?action=deletePage&name=' + escape( page );

  var callback = 
  {
    success : handleDeletePage,
    failure : handleFailure,
    argument : [ page ]
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function handleDeletePage ( obj )
{
  buildIndex( obj );
  
  if ( obj.argument[0] == notebookPageName ) {
    gotoPage( '<%= NotebookManager.DEFAULT_PAGE_NAME %>', 'def' );
  }
}

function gotoPage ( page, ind )
{
  var surl = 'notebook?action=setDefaultPage&name=' + escape( page );

  var callback = 
  {
    success : handleGotoPage,
    failure : handleFailure,
    argument : [ page, ind ]
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function handleGotoPage ( obj )
{
  //remove current overlays
  var pages = document.getElementById( "pages" );
  while ( pages.hasChildNodes() ) {
    pages.removeChild( pages.firstChild );
  }

  ( new YAHOO.util.Element( "pages" ) ).setStyle( "left", "0px" );
  ( new YAHOO.util.Element( "scrubber" ) ).setStyle( "left", "0px" );

  notebookPageName = obj.argument[0];

  //populate with new notes
  getNotebookEntries();

  //clear the page indictors
  var sps = ( new YAHOO.util.Element( "notebookIndex" ) ).getElementsByClassName( "indexIndicator" );
  for ( var i = 0; i < sps.length; i++ ) {
    sps[i].innerHTML = "";
  }

  //set the current page indicator
  var sp = document.getElementById( "indexIndicator_" + obj.argument[1] );
  sp.innerHTML = "&#9658; ";  
}

function getNotebookIndex ()
{
  var surl = 'notebook?action=list';

  var callback = 
  {
    success : buildIndex,
    failure : handleFailure
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function buildIndex ( obj )
{
  var doc = obj.responseXML;

  var pages = doc.getElementsByTagName( "page" );

  var pageDiv = document.getElementById( "notebookPages" );
  while ( pageDiv.hasChildNodes() ) { pageDiv.removeChild( pageDiv.firstChild ); }

  for ( var i = 0; i < pages.length; i++ ) {
    var name = pages.item( i ).getAttribute( "name" );
    var notesSize = pages.item( i ).getAttribute( "size" );
    
    var d = document.createElement( "DIV" );
    d.setAttribute( "class", "notebookIndexEntry" );

    var t = document.createElement( "TABLE" );
    t.setAttribute( "width", "100%" );
    t.setAttribute( "cellpadding", "0" );
    t.setAttribute( "cellspacing", "0" );
    t.setAttribute( "margin", "0" );
    
    var tr = document.createElement( "TR" );
    var td_name = document.createElement( "TD" );
    var sp = document.createElement( "SPAN" );
    sp.setAttribute( "id", "indexIndicator_" + i );    
    sp.setAttribute( "class", "indexIndicator" );

    if ( name == notebookPageName ) {
      sp.innerHTML = "&#9658; ";
    }
    
    td_name.appendChild( sp );

    var link = document.createElement( "A" );
    link.setAttribute( "class", "notebookIndexLink" );
    link.setAttribute( "href", "javascript:gotoPage( '" + name + "', '" + i + "' )" );
    link.appendChild( document.createTextNode( name ) );
    td_name.appendChild( link );

    var td_del = document.createElement( "TD" );
    td_del.setAttribute( "align", "right" );
    
    if ( notesSize == 0 ) {
      var del = document.createElement( "A" );
      del.setAttribute( "class", "supnavlink" );
      del.setAttribute( "href", "javascript:deletePage( '" + name + "' )" );
      del.appendChild( document.createTextNode( "delete" ) );
      td_del.appendChild( del );
    }

    tr.appendChild( td_name );
    tr.appendChild( td_del );

    t.appendChild( tr );

    d.appendChild( t );

    pageDiv.appendChild( d );
  }
}

function removeNote ( id )
{
  var entry = findNote( id );
  var noteId = entry.getAttribute( "noteId" );

  if ( noteId == '' ) {
    removeAndScrollPagesOver( id );

    if ( getNumPages() == 0 ) {
      getNotebookIndex();
    }

    return;
  }

  var surl = 'note?action=delete&id=' + notebookPageName + '&noteId=' + noteId;

  var callback = 
  {
    success : handleDelete,
    failure : handleFailure,
    argument : id
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function handleDelete ( obj )
{
  var entry = findNote( obj.argument );

  removeAndScrollPagesOver( obj.argument );

  if ( getNumPages() == 0 ) {
    getNotebookIndex();
  }
}

function removeAndScrollPagesOver ( afterPageId )
{
  var pages = new YAHOO.util.Element( "pages" );
  var notes = pages.getElementsByClassName( "notebookPage" );

  //scroll the remaining pages over
  var scrollOne = 0
  for ( var i = 0; i < notes.length; i++ ) {
    if ( notes[i].getAttribute( "id" ) == afterPageId ) {
      scrollOne = 1;
    }
    else if ( scrollOne == 1 ) {
      //alert( "scrolling: " + notes[i].getAttribute( "id" ) );
      var relLeft = getRelativeLeft( notes[i].getAttribute( "id" ) );

      var myAnim = new YAHOO.util.Anim( notes[i].getAttribute( "id" ) );
      myAnim.attributes.left = { by:( -1 * ( NOTE_WIDTH + NOTE_PADDING ) ) };
      myAnim.duration = .25;
      myAnim.method = YAHOO.util.Easing.easeBothStrong;
      myAnim.animate();

      if ( relLeft > 0 ) { scrollOne++; }
    }
    else if ( scrollOne > 1 ) {
      //alert( "moving: " + notes[i].getAttribute( "id" ) );
      var el = new YAHOO.util.Element( notes[i].getAttribute( "id" ) );
      el.setStyle( "left", ( i - 1 ) * ( NOTE_WIDTH + NOTE_PADDING ) );
    }
  }

  //remove the page
  document.getElementById( "pages" ).removeChild( document.getElementById( afterPageId ) );

  resetScrubber();
}

function getRelativeLeft ( id )
{
  var el = new YAHOO.util.Element( id );
  var elLeft = getValForStyle( el.getStyle( "left" ) );
  var pages = new YAHOO.util.Element( "pages" );
  var pagesLeft = getValForStyle( pages.getStyle( "left" ) );
  return ( ( ( pagesLeft * 1 ) + elLeft ) - ( NOTE_WIDTH + NOTE_PADDING ) );
}

function getNotebookEntries ()
{
  var surl = 'note?action=getNotes&id=' + notebookPageName;

  var callback = 
  {
    success : parseNotebookDoc,
    failure : handleFailure
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function parseNotebookDoc ( obj )
{
  var doc = obj.responseXML;
  var notes = doc.getElementsByTagName( "note" );

  var indexOffset = ( sidebar.isSidebarOpen ? -250 : 0 );

  for ( var i = 0; i < notes.length; i++ ) {
    var noteId = notes.item( i ).getAttribute( "id" );
    var year = notes.item( i ).getAttribute( "year" );
    var month = notes.item( i ).getAttribute( "month" );
    var date = notes.item( i ).getAttribute( "date" );
    var time = notes.item( i ).getAttribute( "time" );
    var height = notes.item( i ).getAttribute( "height" );
    var width = notes.item( i ).getAttribute( "width" );
    var top = notes.item( i ).getAttribute( "top" );
    var left = Number( notes.item( i ).getAttribute( "left" ) ) + Number( indexOffset );
    var content = notes.item( i ).childNodes.item( 0 ).nodeValue;

    newNotebookEntry( noteId, formatDate( year, month, date, time ), 
                      height, width, top, left, content );
  }
  
  //add a fresh page
  addNotebookEntry();

  //scroll to the end
  if ( getNumPages() > 2 ) {
    scroll( -1 * ( getNumPages() - 2 ) * ( NOTE_WIDTH + NOTE_PADDING ), parseInt( NOTE_WIDTH / getNumPages() ) * ( getNumPages() - 2 ) );
  }
}

function saveNote ( id )
{
  var note = findNote( id );
  var left = 0;
  var right = 0;
  var width = 0;
  var height = 0;
  //var region = YAHOO.util.Dom.getRegion( note.element );
  //var left = region.left;
  //var top = region.top;
  //var width = region.right - region.left;
  //var height = region.bottom - region.top;
  var year = note.getAttribute( "year" );
  var month = note.getAttribute( "month" );
  var date = note.getAttribute( "date" );
  var noteId = note.getAttribute( "noteId" );

  var editor = TinyEditor.getEditor( id + '_data' );
  var content = editor.getValue();

  var surl = 'note?action=save&id=' + notebookPageName +
             '&data=' + escape( content ) + '&noteId=' + noteId +
             '&year=' + year + '&month=' + month + '&date=' + date +
             '&width=' + width + '&height=' + height +
             '&top=' + top + '&left=' + left;

  var callback = 
  {
    success : handleSaveNote,
    failure : handleFailure,
    argument : id
  };

  YAHOO.util.Connect.asyncRequest( 'GET', surl, callback );
}

function handleSaveNote ( obj )
{
  //set the right note id for new saved note objects
  var note = findNote( obj.argument );
  var noteId = obj.responseXML.getElementsByTagName( "notes" )[0].getAttribute( "savedNoteId" );
  note.setAttribute( "noteId", noteId );

  //lock the editor
  var editor = TinyEditor.getEditor( obj.argument + "_data" );
  editor.lock();  

  //hide the save link
  var saveLinkDiv = new YAHOO.util.Element( obj.argument + "_saveLink" );
  saveLinkDiv.setStyle( "visibility", "hidden" );

  //rebuild the index if this is the first note we're saving
  if ( getNumPages() == 1 ) {
    getNotebookIndex();
  }
}

function handleFailure ( obj )
{
  alert( "Problem: " + obj.statusText + " (" + obj.status + ")" ); 
}

function showSaveLink ( id )
{
  var editor = TinyEditor.getEditor( id + "_data" );
  if ( editor.hasText() ) {
    var saveLinkDiv = new YAHOO.util.Element( id + "_saveLink" );
    saveLinkDiv.setStyle( "visibility", "visible" );
  }
}

function handleTextChangedEvent ( type, args, me )
{
  showSaveLink( me );
}

function handleSaveCall ( type, args, me )
{
  saveNote( me );
}

function handleDragEvent ( type, args, vals )
{
  if ( args[0] == 'startDrag' ) { 
    vals[1].hide();
    TinyEditor.globalLock = true;
  }
  if ( args[0] == 'endDrag' ) {
    vals[1].show();
    showSaveLink( vals[0] ); 
    TinyEditor.globalLock = false;
  }
}

function getNumPages ()
{
  var pages = new YAHOO.util.Element( "pages" );
  return pages.getElementsByClassName( "notebookPage" ).length;
}

function findNote ( id )
{
  var pages = document.getElementById( "pages" );
  var notes = pages.getElementsByTagName( "div" );
  for ( var i = 0; i < notes.length; i++ ) {
    var note = notes.item( i );
    if ( note.getAttribute( "id" ) == id ) {
      return note;
    }
  }
}

var NOTE_Y_OFFSET = 50;
var NOTE_PADDING = 20;
var NOTE_WIDTH = 350;
var NOTE_HEIGHT = YAHOO.util.Dom.getViewportHeight() - ( NOTE_Y_OFFSET * 2 ) - 30;

var masterIndex = 0;

function addNotebookEntry ()
{
  var page = document.getElementById( "pages" ).lastChild;
  if ( page && page.getAttribute( "noteId" ) != "" )
  {
    page = newNotebookEntry( '', today, 300, 250, 50, 100, '' );
  }

  //scroll to the last page if need to
  var relLeft = getRelativeLeft( page.getAttribute( "id" ) );
  if ( relLeft > 0 ) {
    scroll( -1 * relLeft, parseInt( NOTE_WIDTH / getNumPages() ) * ( relLeft / ( NOTE_WIDTH + NOTE_PADDING ) ) ); 
  }
}

function newNotebookEntry ( noteId, noteDate, noteHeight, noteWidth, noteTop, noteLeft, noteContent )
{
  var numPages = getNumPages();
  var xpos = NOTE_WIDTH * numPages + 20 * numPages;

  //var name = 'note_' + ( ( numPages * 1 ) + 1 );
  var name = 'note_' + masterIndex++;

  var np = document.createElement( "div" );
  np.setAttribute( "id", name );
  np.setAttribute( "class", "notebookPage" );

  var notename = notebookPageName;
  if ( notename == "<%= NotebookManager.DEFAULT_PAGE_NAME %>" ) {
    notename = "Page One";
  }

  np.innerHTML = "<table class='noteHeader' cellpadding='0' cellspacing='0' border='0' width='100%'><tr><td class='noteDate'>" + notename + "</td><td class='noteActions'><span id='" + name + "_saveLink' class='saveNoteLink'><a class='noteActionLink' href=\"javascript:saveNote( '" + name + "' )\">save</a> | </span><a class='noteActionLink' href=\"javascript:removeNote( '" + name + "' )\">delete</a></td></tr></table>";

  np.innerHTML += "<div class='noteBody'><textarea id='" + name + "_data' class='editor'>" + noteContent + "</textarea></div>";

  np.setAttribute( "year", "" );
  np.setAttribute( "month", "" );
  np.setAttribute( "date", "" );
  np.setAttribute( "noteId", noteId );

  document.getElementById( "pages" ).appendChild( np );
  
  var npel = new YAHOO.util.Element( name );
  npel.setStyle( "left", xpos );

  var editor = new TinyEditor( name + '_data', 'include/tinyEditor_css.jsp' );
  editor.init();

  editor.textChanged.subscribe( handleTextChangedEvent, name ); 
  editor.saveCall.subscribe( handleSaveCall, name );

  if ( noteId == '' ) {
    editor.focus();
    editor.unlock();
  }

  resetScrubber();

  return np;
}

function resetScrubber ()
{
  var pages = new YAHOO.util.Element( "pages" );
  var scrub = new YAHOO.util.Element( "scrubber" );
  scrub.setStyle( "width", parseInt( NOTE_WIDTH / ( getNumPages() / 2 ) ) );

  var leftPos = getValForStyle( pages.getStyle( "left" ) );
  scrub.setStyle( "left", ( ( -1 * leftPos / ( NOTE_WIDTH + NOTE_PADDING ) ) ) * ( parseInt( NOTE_WIDTH / getNumPages() ) ) );
}


var months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];

function getMonth ( m )
{
  return months[m];
}

function formatDate ( year, month, date, time )
{
  return getMonth( month ) + " " + date + ", " + year;
}

getNotebookIndex();
getNotebookEntries();

<% GregorianCalendar cal = DateFactory.getInstance().getCalendar(); %>

var today = formatDate( '<%= cal.get( Calendar.YEAR ) %>', '<%= cal.get( Calendar.MONTH ) %>', '<%= cal.get( Calendar.DATE ) %>', '' );

//situate things on the page

var el = new YAHOO.util.Element( "container" )
el.setStyle( "width", NOTE_WIDTH * 2 + 20 );
el.setStyle( "height", YAHOO.util.Dom.getViewportHeight() - ( 50 * 3 ) );
el.setStyle( "left", YAHOO.util.Dom.getViewportWidth() / 2 - ( NOTE_WIDTH + 10 ) );

var sc = new YAHOO.util.Element( "scrubberBar" );
sc.setStyle( "left", YAHOO.util.Dom.getViewportWidth() / 2 - 175 );

//handle swipe events

var oElement = document.getElementById("container");
YAHOO.util.Event.addListener(oElement, "mousewheel", scrollPage);

var wheelDelta = 0;
var waitTimer;

function scrollPage ( e ) 
{ 
  if ( wheelDelta == 0 ) {
    wheelDelta = e.wheelDelta;

    var p = new YAHOO.util.Element( 'pages' );
    var oleftVal = getValForStyle( p.getStyle( "left" ) );

    var numPages = getNumPages();

    if ( wheelDelta > 0 && oleftVal > ( ( numPages - 1 ) * -320 ) ) {
      scroll( ( 0 - ( NOTE_WIDTH + NOTE_PADDING ) ), parseInt( NOTE_WIDTH / numPages ) );
    }
    else if ( wheelDelta <= 0 && oleftVal < 0 ) {
      scroll( ( NOTE_WIDTH + NOTE_PADDING ), 0 - parseInt( NOTE_WIDTH / numPages ) );
    }
    else {
      clearTimeout( waitTimer );
      waitTimer = setTimeout( finishScrollPage, 250 );
    }
  }
}

function getValForStyle ( styleTxt )
{
   return parseInt( styleTxt.substring( 0, styleTxt.indexOf( "px" ) ), 10 );
}

function scroll ( extent, scrubExtent )
{
  var myAnim = new YAHOO.util.Anim( 'pages' );
  myAnim.attributes.left = { by:extent };
  myAnim.duration = .25;
  myAnim.method = YAHOO.util.Easing.easeBothStrong;
  myAnim.onComplete.subscribe( finishScrollPage );

  var sAnim = new YAHOO.util.Anim( 'scrubber' );
  sAnim.attributes.left = { by:scrubExtent };
  sAnim.duration = .25;
  sAnim.method = YAHOO.util.Easing.easeBothStrong;

  myAnim.animate();
  sAnim.animate();
}

function finishScrollPage ()
{
  wheelDelta = 0;
}

</script>

</html>
